package virtorina.client.room;

import java.util.Date;
import virtorina.client.room.dto.UserDTO;
import virtorina.client.room.rpc.GWTService4Room;
import virtorina.client.room.rpc.GWTService4RoomAsync;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Text;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.Window;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */

public class Virtorina implements EntryPoint {
	Chat chat;
	Users users;
	Main main;
	String name;
	private Integer ROOM_ID;

	public void onModuleLoad() {
		try {
			String value = com.google.gwt.user.client.Window.Location
					.getParameter("id");
			ROOM_ID = new Integer(value);
			if (ROOM_ID == null) {
				Window.open("../rooms.html", "_self", "");
			}
			((GWTService4RoomAsync) GWT.create(GWTService4Room.class)).getName(
					ROOM_ID, new AsyncCallback<String>() {

						@Override
						public void onSuccess(String result) {
							if (result.equals("@@@")) {
								Window.open("../rooms.html", "_self", "");
							} else {
								name = result;
							}

						}

						@Override
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub

						}
					});
		} catch (Exception e) {
			Window.open("../rooms.html", "_self", "");
		}
		chat = new Chat(ROOM_ID, this);
		users = new Users(ROOM_ID, this);
		main = new Main(ROOM_ID, this);
		HTML feedback = HTML.wrap(RootPanel.get("feedback").getElement());
		feedback.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				SendFeedback();
			}
		});
		setUser();
		Label quest_message = new Label();
		quest_message.setText("Question");
		// RootPanel.get("message").add(quest_message);
		RootPanel.get("Ulist").add(users.getUsers());
		RootPanel.get("chat").add(chat.getChat());
		// HTML name = HTML.wrap(RootPanel.get("userName").getElement());
		// name.setHTML("<a href=\"https://loginza.ru/api/widget?token_url=http://hierofeus.appspot.com/auth\"	class=\"loginza\">Представиться</a>");

		setExit();

	}

	private void setExit() {
		Window.addCloseHandler(new CloseHandler<Window>() {

			@Override
			public void onClose(CloseEvent<Window> event) {
				leave();

			}
		});

	}

	private void leave() {
		System.out.println("Attempt to exit");
		((GWTService4RoomAsync) GWT.create(GWTService4Room.class)).leave(
				ROOM_ID, new AsyncCallback<Void>() {

					@Override
					public void onSuccess(Void result) {
					}

					@Override
					public void onFailure(Throwable caught) {
					}
				});
	}

	private Long UserID;
	private String UserName = null;

	private void setUser() {
		((GWTService4RoomAsync) GWT.create(GWTService4Room.class)).getUser(
				ROOM_ID, new AsyncCallback<UserDTO>() {

					@Override
					public void onSuccess(UserDTO result) {
						if (result == null) {
							MultyLoginError();
							return;
						}

						UserID = result.getID();
						if (result.getName() == null) {
							setName();
						} else {
							HTML name = HTML.wrap(RootPanel.get("userName")
									.getElement());
							name.setHTML(result.getName());
							UserName = result.getName();
						}
						prepair();
					}

					@Override
					public void onFailure(Throwable caught) {
						System.out.println("Failed to get User");

					}
				});
	}

	boolean ready = false;

	private void prepair() {
		chat.startUpdates(UserID);
		main.start();
		chat.setlastMessageTime(new Date().getTime());
		UpdateTimer.run();
		UpdateTimer.scheduleRepeating(2000);
		if (UserName != null) {
			chat.startWriting(UserName);
			users.setUser(new UserDTO(UserID, UserName));
		}
		return;
	}

	final DialogBox RegisterBox = new DialogBox();

	private void MultyLoginError() {
		final DialogBox MultyLoginBox = new DialogBox();
		MultyLoginBox.setAnimationEnabled(true);
		MultyLoginBox.setText("Only one user session per user is allowed");
		// MultyLoginBox.setHTML("")

	}

	public void SendFeedback() {
		final DialogBox Feedback = new DialogBox();
		Feedback.setWidth("600px");
		Feedback.addStyleName("width600");
		Feedback.setAnimationEnabled(true);
		Feedback.setAnimationEnabled(true);
		final TextBox nameField = new TextBox();
		Feedback.setText("Say something to us");
		final VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		final Button apply = new Button("Back to the game");
		apply.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Feedback.hide();

			}
		});
		dialogVPanel.add(new HTML(
				"<h3>You may connect with us using this form</h3>"));

		Frame frame = new Frame("copinyframe.html");
		frame.setStyleName("noBorder");
		dialogVPanel.add(frame);
		HTML email = new HTML(
				"<hr><b>Or write to our email</b> <br> <a  target=\"_blank\" href=\"mailTo:mialerxD+iq@gmail.com\">mialerxD+iq@gmail.com</a><br><hr>");
		dialogVPanel.add(email);
		frame.setWidth("600px");
		frame.setHeight("320px");

		dialogVPanel.add(apply);
		Feedback.add(dialogVPanel);
		Feedback.center();
		nameField.setFocus(true);
	};

	private void setName() {
		RegisterBox.setAnimationEnabled(true);
		final TextBox nameField = new TextBox();
		RegisterBox.setText("Choose a name:");
		final VerticalPanel dialogVPanel = new VerticalPanel();
		final Label respText = new Label();
		final Button apply = new Button("I choose this one!");
		respText.setText("Enter the name");
		dialogVPanel.add(nameField);
		dialogVPanel.add(respText);
		dialogVPanel.add(apply);
		RegisterBox.add(dialogVPanel);
		RegisterBox.center();
		nameField.setFocus(true);
		apply.setEnabled(false);
		apply.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				UpdateName(nameField.getText());

			}

		});
		nameField.addKeyUpHandler(new KeyUpHandler() {

			@Override
			public void onKeyUp(KeyUpEvent event) {
				if (nameField.getText().length() > 20) {
					respText.setText("The name is too long");
					apply.setEnabled(false);
				} else if (nameField.getText().length() < 4) {
					respText.setText("The name is too short");
					apply.setEnabled(false);
				} else if (nameField.getText().charAt(0) == ' ') {
					respText.setText("The name can't begin with space");
					apply.setEnabled(false);
				} else if (nameField.getText().charAt(
						nameField.getText().length() - 1) == ' ') {
					respText.setText("The name can't end with space");
					apply.setEnabled(false);
				} else if (nameField.getText().contains("  ")) {
					respText.setText("No more than one consecutive space");
					apply.setEnabled(false);
				} else {
					validate(nameField.getText());
				}
			}

			private void validate(String text) {
				text = chat.HTMLreplace(text);
				((GWTService4RoomAsync) GWT.create(GWTService4Room.class))
						.validate(text, new AsyncCallback<Boolean>() {

							@Override
							public void onFailure(Throwable caught) {
							}

							@Override
							public void onSuccess(Boolean result) {
								if (result) {
									respText.setText("The name is free!");
									apply.setEnabled(true);
								} else {
									respText.setText("The name is taken. Please try another one");
									apply.setEnabled(false);

								}
							}
						});

			}

		});
	}

	private void UpdateName(String text) {
		RegisterBox.hide();
		text = chat.HTMLreplace(text);
		((GWTService4RoomAsync) GWT.create(GWTService4Room.class)).updateName(
				text, ROOM_ID, new AsyncCallback<String>() {

					@Override
					public void onFailure(Throwable caught) {
					}

					@Override
					public void onSuccess(String result) {
						UserName = result;
						chat.startWriting(UserName);
						users.setUser(new UserDTO(UserID, UserName));
						HTML name = HTML.wrap(RootPanel.get("userName")
								.getElement());
						name.setHTML(result);
					}
				});
	}

	private Timer UpdateTimer = new Timer() {
		@Override
		public void run() {

			((GWTService4RoomAsync) GWT.create(GWTService4Room.class))
					.getUpdates(ROOM_ID, new AsyncCallback<Integer>() {
						@Override
						public void onFailure(Throwable caught) {
						}

						@Override
						public void onSuccess(Integer result) {
							if (result == 1) {
								chat.checkNewMessages();
							} else if (result == 2) {
								users.chekNewUsers();
							} else if (result == 3) {
								users.checkLeaveUsers();
							} else if (result == 4) {
								main.getQuestion();
							} else if (result == 5) {
								main.getInfo();
							}
						}

					});

		}
	};
}
